package es.esi.gemde.methodmanager.service.ui;

import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

import es.esi.gemde.core.CorePlugin;
import es.esi.gemde.methodmanager.CommandConstants;
import es.esi.gemde.methodmanager.methodmodel.method.CallWizardCommand;
import es.esi.gemde.methodmanager.methodmodel.method.DataStorageElement;
import es.esi.gemde.methodmanager.methodmodel.method.InternalVariable;
import es.esi.gemde.methodmanager.methodmodel.method.LaunchTransformationCommand;
import es.esi.gemde.methodmanager.methodmodel.method.LaunchValidationCommand;
import es.esi.gemde.methodmanager.methodmodel.method.MethodFactory;
import es.esi.gemde.methodmanager.methodmodel.method.MethodVariable;
import es.esi.gemde.methodmanager.methodmodel.method.OpenEditorCommand;
import es.esi.gemde.methodmanager.methodmodel.method.RepeatedSubTask;
import es.esi.gemde.methodmanager.methodmodel.method.SelectFileCommand;
import es.esi.gemde.methodmanager.methodmodel.method.SelectFolderCommand;
import es.esi.gemde.methodmanager.methodmodel.method.SelectModelElementFromEObjectCommand;
import es.esi.gemde.methodmanager.methodmodel.method.SelectModelElementFromFileCommand;
import es.esi.gemde.methodmanager.methodmodel.method.SimpleCommand;
import es.esi.gemde.methodmanager.methodmodel.method.VariableCommandParameter;

public class AddVariableStandardParameterDialog extends Dialog {

	private String parameterID;
	private DataStorageElement variable;
	private SimpleCommand command;
	private Button okButton;
	
	
	public AddVariableStandardParameterDialog(Shell parentShell, SimpleCommand command) {
		super(parentShell);
		this.command = command;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
	 */
	@Override
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText("Create Standard Parameter");
		newShell.setImage(CorePlugin.getImage(CorePlugin.VARIABLE_PARAM_ICON));
		//newShell.setSize(300, 400);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		Composite topPanel = new Composite(parent, SWT.NONE);
		GridLayout layout = new GridLayout(4, true);
		topPanel.setLayout(layout);


		Label elem0 = new Label(topPanel, SWT.NONE);
		GridData elem0Data = new GridData(GridData.FILL_HORIZONTAL);
		elem0Data.horizontalSpan = 1;
		elem0.setText("Standard Param.:");
		elem0.setLayoutData(elem0Data);

		Combo elem1 = new Combo(topPanel, SWT.BORDER | SWT.READ_ONLY);
		GridData elem1Data = new GridData(GridData.FILL_HORIZONTAL);
		elem1Data.horizontalSpan = 3;
		elem1.setLayoutData(elem1Data);
		elem1.addSelectionListener(new SelectionListener() {
			
			@Override
			public void widgetSelected(SelectionEvent e) {
				parameterID = ((Combo)e.widget).getItem(((Combo)e.widget).getSelectionIndex());
				checkCompleted();
			}
			
			@Override
			public void widgetDefaultSelected(SelectionEvent e) {}
		});

		Label elem2 = new Label(topPanel, SWT.NONE);
		GridData elem2Data = new GridData(GridData.FILL_HORIZONTAL);
		elem2Data.horizontalSpan = 1;
		elem2.setText("Variable:");
		elem2.setLayoutData(elem2Data);

		ComboViewer elem3 = new ComboViewer(topPanel, SWT.BORDER | SWT.READ_ONLY);
		GridData elem3Data = new GridData(GridData.FILL_HORIZONTAL);
		elem3Data.horizontalSpan = 3;
		elem3.getCombo().setLayoutData(elem3Data);
		elem3.addSelectionChangedListener(new ISelectionChangedListener() {
			
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				Object o = ((StructuredSelection)event.getSelection()).getFirstElement();
				if (o instanceof DataStorageElement) {
					variable = (DataStorageElement) o;
				}
				else {
					variable = null;
				}
				checkCompleted();
			}
		});
		elem3.setLabelProvider(new LabelProvider() {
			
			@Override
			public String getText(Object element) {
				if (element instanceof MethodVariable) {
					return ((MethodVariable)element).getName();
				}
				else if (element instanceof InternalVariable) {
					InternalVariable iv = (InternalVariable) element;
					return ((RepeatedSubTask)iv.eContainer()).getTitle() + "::" +iv.getName();
				}
				else {
					return element.toString();
				}
			}
			
		});
		
		// Fill the list according to the command type
		if (command instanceof CallWizardCommand) {
			elem1.add(CommandConstants.WIZARD_PARAM_ID);
		}
		else if (command instanceof SelectFileCommand) {
			elem1.add(CommandConstants.ONLYWORKSPACE_PARAM_ID);
		}
		else if (command instanceof SelectFolderCommand) {
			elem1.add(CommandConstants.ONLYWORKSPACE_PARAM_ID);
		}
		else if (command instanceof SelectModelElementFromFileCommand) {
			elem1.add(CommandConstants.MODELFILE_PARAM_ID);
			elem1.add(CommandConstants.ADDTOLIST_PARAM_ID);
			elem1.add(CommandConstants.LIST_PARAM_ID);
		}
		else if (command instanceof SelectModelElementFromEObjectCommand) {
			elem1.add(CommandConstants.EOBJECT_PARAM_ID);
			elem1.add(CommandConstants.ADDTOLIST_PARAM_ID);
			elem1.add(CommandConstants.LIST_PARAM_ID);
		}
		else if (command instanceof LaunchValidationCommand) {
			elem1.add(CommandConstants.VALIDATION_PARAM_ID);
			elem1.add(CommandConstants.EOBJECT_PARAM_ID);
			elem1.add(CommandConstants.MODELFILE_PARAM_ID);
		}
		else if (command instanceof LaunchTransformationCommand) {
			elem1.add(CommandConstants.TRANSFORMATION_PARAM_ID);
			elem1.add(CommandConstants.INPUTS_PARAM_ID);
			elem1.add(CommandConstants.OUTPUTPATH_PARAM_ID);
		}
		else if (command instanceof OpenEditorCommand) {
			elem1.add(CommandConstants.EDITORID_PARAM_ID);
			elem1.add(CommandConstants.FILE_PARAM_ID);
		}
		
		// Fill the combo with variables
		TreeIterator<EObject> i = command.eContainer().eAllContents();
		while (i.hasNext()) {
			EObject o = i.next();
			if (o instanceof DataStorageElement) {
				elem3.add(o);
			}
		}

		return topPanel;
	}
	
	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		// Only create an OK button
		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
		okButton = getButton(IDialogConstants.OK_ID);
		checkCompleted();
	}
	
	private void checkCompleted() {
		
		boolean enableOk = false;
		
		enableOk = parameterID != null && variable != null;
		
		if (okButton != null) {
			okButton.setEnabled(enableOk);
		}
	}
	
	public VariableCommandParameter createSelectedCommandParameter() {
		VariableCommandParameter p = MethodFactory.eINSTANCE.createVariableCommandParameter();
		p.setIdentifier(parameterID);
		p.setValue(variable);
		
		if (command instanceof CallWizardCommand) {
			if (parameterID.equals(CommandConstants.WIZARD_PARAM_ID)) {
				((CallWizardCommand)command).setWizard(p);
			}
		}
		else if (command instanceof SelectFileCommand) {
			if (parameterID.equals(CommandConstants.ONLYWORKSPACE_PARAM_ID)) {
				((SelectFileCommand)command).setOnlyWorkspace(p);
			}
		}
		else if (command instanceof SelectFolderCommand) {
			if (parameterID.equals(CommandConstants.ONLYWORKSPACE_PARAM_ID)) {
				((SelectFolderCommand)command).setOnlyWorkspace(p);
			}
		}
		else if (command instanceof SelectModelElementFromFileCommand) {
			if (parameterID.equals(CommandConstants.MODELFILE_PARAM_ID)) {
				((SelectModelElementFromFileCommand)command).setModelFile(p);
			}
			else if (parameterID.equals(CommandConstants.ADDTOLIST_PARAM_ID)) {
				((SelectModelElementFromFileCommand)command).setAddToList(p);
			}
			else if (parameterID.equals(CommandConstants.LIST_PARAM_ID)) {
				((SelectModelElementFromFileCommand)command).setList(p);
			}
		}
		else if (command instanceof SelectModelElementFromEObjectCommand) {
			if (parameterID.equals(CommandConstants.EOBJECT_PARAM_ID)) {
				((SelectModelElementFromEObjectCommand)command).setEObject(p);
			}
			else if (parameterID.equals(CommandConstants.ADDTOLIST_PARAM_ID)) {
				((SelectModelElementFromEObjectCommand)command).setAddToList(p);
			}
			else if (parameterID.equals(CommandConstants.LIST_PARAM_ID)) {
				((SelectModelElementFromEObjectCommand)command).setList(p);
			}
		}
		else if (command instanceof LaunchValidationCommand) {
			if (parameterID.equals(CommandConstants.VALIDATION_PARAM_ID)) {
				((LaunchValidationCommand)command).setValidation(p);
			}
			else if (parameterID.equals(CommandConstants.EOBJECT_PARAM_ID)) {
				((LaunchValidationCommand)command).setEobject(p);
			}
			else if (parameterID.equals(CommandConstants.MODELFILE_PARAM_ID)) {
				((LaunchValidationCommand)command).setModelFile(p);
			}
		}
		else if (command instanceof LaunchTransformationCommand) {
			if (parameterID.equals(CommandConstants.TRANSFORMATION_PARAM_ID)) {
				((LaunchTransformationCommand)command).setTransformation(p);
			}
			else if (parameterID.equals(CommandConstants.INPUTS_PARAM_ID)) {
				((LaunchTransformationCommand)command).setInputs(p);
			}
			else if (parameterID.equals(CommandConstants.OUTPUTPATH_PARAM_ID)) {
				((LaunchTransformationCommand)command).setOutputPath(p);
			}
			else if (parameterID.equals(CommandConstants.OUTPUTS_PARAM_ID)) {
				((LaunchTransformationCommand)command).setOutputs(p);
			}
		}
		else if (command instanceof OpenEditorCommand) {
			if (parameterID.equals(CommandConstants.EDITORID_PARAM_ID)) {
				((OpenEditorCommand)command).setEditorID(p);
			}
			else if (parameterID.equals(CommandConstants.FILE_PARAM_ID)) {
				((OpenEditorCommand)command).setOpenedFile(p);
			}
		}
		
		return p;
	}
}
